package com.hyz.reggie.service.Impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hyz.reggie.common.RedisKeys;
import com.hyz.reggie.dao.DishDao;
import com.hyz.reggie.dto.DishDto;
import com.hyz.reggie.pojo.*;
import com.hyz.reggie.service.CategoryService;
import com.hyz.reggie.service.DishFlavorService;
import com.hyz.reggie.service.DishService;
import com.hyz.reggie.service.SetmealDishService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DishServiceImpl extends ServiceImpl<DishDao, Dish> implements DishService {
    @Autowired
    private DishFlavorService service;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private SetmealDishService setmealDishService;

    @Override
    public void saveDish(DishDto dishDto) {
        save(dishDto);
        List<DishFlavor> flavors = dishDto.getFlavors();
        Long dishId = dishDto.getId();
        flavors.stream().forEach(c -> c.setDishId(dishId));
        service.saveBatch(flavors);
    }

    @Override
    public IPage<DishDto> findByPage(Integer page, Integer pageSize, String name) {
        IPage<Dish> iPage = new Page<>(page, pageSize);
        LambdaQueryWrapper<Dish> qwq = new LambdaQueryWrapper();
        if (name != null) {
            qwq.like(Dish::getName, name);
        }
        qwq.orderByDesc(Dish::getUpdateTime);
        iPage = page(iPage, qwq);
        List<Dish> dishs = iPage.getRecords();
        List<DishDto> dishDtos = JSON.parseArray(JSON.toJSONString(dishs), DishDto.class);
        dishDtos.stream().forEach(c -> {
            Long categoryId = c.getCategoryId();
            Category category = categoryService.getById(categoryId);
            c.setCategoryName(category.getName());
        });
        IPage<DishDto> dishDtoIPage = new Page<>();
        dishDtoIPage.setTotal(iPage.getTotal());
        dishDtoIPage.setRecords(dishDtos);
        return dishDtoIPage;
    }

    @Override
    public DishDto modifyDishById(Long id) {
        if (id == null) {
            return null;
        }
        Dish dish = getById(id);
        DishDto dto = new DishDto();
        BeanUtils.copyProperties(dish, dto);
        LambdaQueryWrapper<DishFlavor> qwq = new LambdaQueryWrapper<>();
        qwq.eq(DishFlavor::getDishId, id);
        List<DishFlavor> list = service.list(qwq);
        dto.setFlavors(list);
        return dto;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDishDto(DishDto dishDto) {
        updateById(dishDto);
        List<DishFlavor> flavors = dishDto.getFlavors();
        Long dishId = dishDto.getId();
        flavors.stream().forEach(c -> {
            c.setDishId(dishId);
        });
        LambdaQueryWrapper<DishFlavor> qwq = new LambdaQueryWrapper<>();
        qwq.eq(DishFlavor::getDishId, dishId);
        service.remove(qwq);
        service.saveBatch(flavors);
    }

    @Override
    @Transactional(rollbackFor = AcquireExecption.class)
    public void deleteById(Long[] ids) {
        Arrays.stream(ids).forEach(id -> {
            LambdaQueryWrapper<SetmealDish> qwq = new LambdaQueryWrapper<>();
            qwq.eq(SetmealDish::getDishId, id);
            List<SetmealDish> list = setmealDishService.list(qwq);
            if (list.size() != 0) {
                throw new AcquireExecption("还有菜品在套餐中，无法删除");
            }
            LambdaQueryWrapper<DishFlavor> qaq = new LambdaQueryWrapper<>();
            qaq.eq(DishFlavor::getDishId, id);
            service.remove(qaq);
            removeById(id);
        });
    }

    @Override
    public List<DishDto> getList(Long categoryId, Integer status) {
        LambdaQueryWrapper<Dish> qwq = new LambdaQueryWrapper<>();
        qwq.eq(Dish::getCategoryId, categoryId);
        qwq.eq(Dish::getStatus, 1);
        List<Dish> list = list(qwq);
        List<DishDto> dtoList = JSON.parseArray(JSON.toJSONString(list), DishDto.class);
        dtoList.stream().map(d -> {
            Long id = d.getId();
            LambdaQueryWrapper<DishFlavor> qaq = new LambdaQueryWrapper<>();
            qaq.eq(DishFlavor::getDishId, id);
            List<DishFlavor> flavors = service.list(qaq);
            d.setFlavors(flavors);
            return d;
        }).collect(Collectors.toList());
        return dtoList;
    }

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void deleteByIds(Long[] ids) {
        deleteById(ids);
        Arrays.stream(ids).forEach(id -> {
            Long categoryId = getById(id).getCategoryId();
            redisTemplate.delete(RedisKeys.DISH_ + categoryId);
        });
    }
}
